package com.sky.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sky.annotation.AutoFill;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.entity.DishFlavor;
import com.sky.entity.SetmealDish;
import com.sky.enumeration.OperationType;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.DishFlavorMapper;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetMealDishMapper;
import com.sky.result.PageResult;
import com.sky.service.DishService;
import com.sky.utils.RedisUtil;
import com.sky.vo.DishVO;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class DishServiceImpl implements DishService {

    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private DishFlavorMapper dishFlavorMapper;

    @Autowired
    private SetMealDishMapper setMealDishMapper;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 新增菜品，同时新增菜品的口味
     *
     * @param dish
     * @param dishFlavors
     */
    @Override
    @Transactional
    @AutoFill(OperationType.INSERT)
    public void saveWithFlavor(Dish dish, List<DishFlavor> dishFlavors) {
        // 新增菜品
        dishMapper.insert(dish);
        // 新增菜品成功后，需要新增菜品的口味
        if (dishFlavors != null && !dishFlavors.isEmpty()) {
            dishFlavors.forEach(dishFlavor -> dishFlavor.setDishId(dish.getId()));
            dishFlavorMapper.insert(dishFlavors);
        }
    }

    /**
     * 菜品分页查询
     *
     * @param dishPageQueryDTO
     * @return
     */
    @Override
    public PageResult page(DishPageQueryDTO dishPageQueryDTO) {
        // 创建分页对象
        Page<DishVO> dishPage = new Page<>(dishPageQueryDTO.getPage(), dishPageQueryDTO.getPageSize());
        dishPage = dishMapper.dishPage(dishPage, dishPageQueryDTO);
        long total = dishPage.getTotal();// 获取总条数
        List<DishVO> records = dishPage.getRecords();// 获取结果信息集合
        return new PageResult(total, records);
    }

    /**
     * 批量删除菜品
     *
     * @param ids
     */
    @Override
    @Transactional
    public void deleteBatch(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new IllegalArgumentException("删除参数不能为空");
        }
        // 查询菜品售卖状态
        List<Dish> dishes = dishMapper.selectByIds(ids);
        if (dishes != null && !dishes.isEmpty()) {
            for (Dish dish : dishes) {
                if (Objects.equals(dish.getStatus(), StatusConstant.ENABLE)) {
                    throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);
                }
            }
        }

        // 查询菜品是否关联套餐
        LambdaQueryWrapper<SetmealDish> setmealDishLambdaQueryWrapper = new LambdaQueryWrapper<SetmealDish>()
                .in(SetmealDish::getDishId, ids);
        List<SetmealDish> setMealDishes = setMealDishMapper.selectList(setmealDishLambdaQueryWrapper);
        if (setMealDishes != null && !setMealDishes.isEmpty()) {
            throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
        }

        // 批量删除菜品
        dishMapper.deleteByIds(ids);
        // 批量删除菜品的口味
        LambdaQueryWrapper<DishFlavor> dishFlavorLambdaQueryWrapper = new LambdaQueryWrapper<DishFlavor>()
                .in(DishFlavor::getDishId, ids);
        dishFlavorMapper.delete(dishFlavorLambdaQueryWrapper);
    }

    /**
     * 根据id查询菜品
     *
     * @param id
     * @return
     */
    @Override
    public DishVO getDishWithFlavorById(Long id) {
        Dish dish = dishMapper.selectById(id);
        DishVO dishVO = new DishVO();
        BeanUtils.copyProperties(dish, dishVO);
        LambdaQueryWrapper<DishFlavor> dishFlavorLambdaQueryWrapper = new LambdaQueryWrapper<DishFlavor>()
                .in(DishFlavor::getDishId, id);
        List<DishFlavor> dishFlavors = dishFlavorMapper.selectList(dishFlavorLambdaQueryWrapper);
        dishVO.setFlavors(dishFlavors);
        return dishVO;
    }


    /**
     * 更新菜品和口味
     *
     * @param dish
     * @param dishFlavors
     * @return
     */
    @Override
    @Transactional
    @AutoFill(OperationType.UPDATE)
    public void updateDishWithFlavor(Dish dish, List<DishFlavor> dishFlavors) {
        // 更新菜品数据
        dishMapper.updateById(dish);
        // 查找出关联的口味并删除
        LambdaQueryWrapper<DishFlavor> dishFlavorLambdaQueryWrapper = new LambdaQueryWrapper<DishFlavor>()
                .eq(DishFlavor::getDishId, dish.getId());
        dishFlavorMapper.delete(dishFlavorLambdaQueryWrapper);
        // 插入新的口味
        dishFlavors.forEach(df -> df.setDishId(dish.getId()));
        dishFlavorMapper.insert(dishFlavors);
    }

    /**
     * 修改菜品起售状态
     *
     * @param status
     * @param id
     * @return
     */
    @Override
    @AutoFill(OperationType.UPDATE)
    public void updateDishStatus(Integer status, Long id) {
        Dish dish = Dish.builder().id(id).status(status).build();
        dishMapper.updateById(dish);
    }

    /**
     * 根据分类id查询菜品
     *
     * @param categoryId
     * @return
     */
    @Override
    @ApiOperation("根据分类id查询菜品")
    public List<DishVO> getDishWithFlavorByCategoryId(Long categoryId) {
        String key = "dish_" + categoryId;
        // 查询是否存在缓存菜品
        List<DishVO> dishVOList = (List<DishVO>) redisUtil.get(key);
        if (dishVOList != null && dishVOList.isEmpty()) {
            return dishVOList;
        }
        // 根据分类id查询菜品
        LambdaQueryWrapper<Dish> getDishQueryWrapper = new LambdaQueryWrapper<Dish>()
                .eq(Dish::getCategoryId, categoryId);
        List<Dish> dishes = dishMapper.selectList(getDishQueryWrapper);
        // 遍历每个菜品id查询菜品口味并构建DishVO
        List<DishVO> dishVOS = dishes.stream().map(dish -> {
            DishVO dishVO = new DishVO();
            BeanUtils.copyProperties(dish, dishVO);
            LambdaQueryWrapper<DishFlavor> getDishFlavorQueryWrapper = new LambdaQueryWrapper<DishFlavor>()
                    .eq(DishFlavor::getDishId, dish.getId());
            List<DishFlavor> dishFlavors = dishFlavorMapper.selectList(getDishFlavorQueryWrapper);
            dishVO.setFlavors(dishFlavors);
            return dishVO;
        }).collect(Collectors.toList());
        // 把菜品数据缓存
        redisUtil.set(key, dishVOS);
        return dishVOS;
    }
}
